home *** CD-ROM | disk | FTP | other *** search
- #include "emu.h"
- #include "compare.h"
- #include "const.h"
-
- #define NAN_NONE 0
- #define NAN_SNAN 1
- #define NAN_QNAN 2
-
- extern "C" void shld(void *);
-
- int nan_type(reg& r)
- {
- if (r.exp != EXP_MAX)
- return NAN_NONE;
- if (r.sigh & 0x40000000)
- return NAN_QNAN;
- return NAN_SNAN;
- }
-
- int compare(reg& a, reg& b)
- {
- int a_inf, b_inf; // 0=no, 1=pos, -1=neg
- a_inf = 0;
- if (val_same(a, CONST_PINF))
- a_inf = 1;
- else if (val_same(a, CONST_NINF))
- a_inf = -1;
- b_inf = 0;
- if (val_same(b, CONST_PINF))
- b_inf = 1;
- else if (val_same(b, CONST_NINF))
- b_inf = -1;
- if (a_inf || b_inf)
- {
- if (a_inf == 1)
- if (b_inf == 1)
- return COMP_A_EQ_B;
- else
- return COMP_A_GT_B;
- if (b_inf == 1)
- return COMP_A_LT_B;
-
- if (a_inf == -1)
- if (b_inf == -1)
- return COMP_A_EQ_B;
- else
- return COMP_A_LT_B;
- if (b_inf == -1)
- return COMP_A_GT_B;
- }
- int a_nan = nan_type(a);
- int b_nan = nan_type(b);
- if (a_nan || b_nan)
- {
- if ((a_nan == NAN_SNAN) || (b_nan == NAN_SNAN))
- return COMP_NOCOMP | COMP_SNAN | COMP_NAN;
- return COMP_NOCOMP | COMP_NAN;
- }
- if (a.sign != b.sign)
- {
- if ((a.tag == TW_Z) && (b.tag == TW_Z))
- return COMP_A_EQ_B;
- if (a.sign == SIGN_POS)
- return COMP_A_GT_B;
- return COMP_A_LT_B;
- }
- while (!(a.sigh & 0x80000000))
- {
- if (!a.exp)
- break;
- shld(&a.sigl);
- a.exp--;
- }
- while (!(b.sigh & 0x80000000))
- {
- if (!b.exp)
- break;
- shld(&b.sigl);
- b.exp--;
- }
- int diff = a.exp - b.exp;
- if (diff == 0) diff = a.sigh - b.sigh;
- if (diff == 0) diff = a.sigl - b.sigl;
- if (diff > 0) return COMP_A_GT_B;
- if (diff < 0) return COMP_A_LT_B;
- return COMP_A_EQ_B;
- }
-